﻿using AM.Communication.Entity;
using FinalTestMachine.Motion;
using FinalTestMachine.Motion.IO;
using FinalTestMachine.Motion.Process;
using Org.BouncyCastle.Asn1.Ocsp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using UdpWpfDemo3;
using WpfZMotion_FinalTestMachine.Core.AWB;
using static FinalTestMachine.Connect.SiteUdpConnectBase;

namespace FinalTestMachine.Connect
{
    public class SiteConnectManager
    {
        public static readonly SiteConnectManager Cur = new SiteConnectManager();
        public static SiteConnectManager CreateInstance()
        {
            return Cur;
        }
        private List<SiteCommunicationHelper> siteUdpConnectBases = new List<SiteCommunicationHelper>();
        public void SetLimit(bool tag)
        {
            foreach (var item in siteUdpConnectBases)
            {
                item.IsLimit = tag;
            }
        }
        private SiteConnectManager() {
            //创建对应数量的通讯对象
            for (int i = 0; i < GlobalParams.WorkstationSum; i++) {
                siteUdpConnectBases.Add(new SiteCommunicationHelper(ConnectFactory.GetTestStationConnect(i+1) , "工位" + (i+1)));
            }
            AddCommand();
        }
        /// <summary>
        /// 获取指定工位的通讯助手（下标从0开始）
        /// </summary>
        /// <param name="index">第几个工站</param>
        /// <returns></returns>
        /// <exception cref="IndexOutOfRangeException"></exception>
        public SiteCommunicationHelper GetCommunicationHelper(int index) {
            if (index > siteUdpConnectBases.Count || index == 0) {
                throw new IndexOutOfRangeException("获取的通讯帮助类超出索引界限！index = " + index);
            }
            return siteUdpConnectBases[index-1];
        }

        //添加各个工位通讯对象的命令和处理方法

        public void AddCommand()
        {
            AddStation1Command();
            AddStation2Command();
            AddStation3Command();
            AddStation4Command();
            AddStation5Command();
            AddStation6Command();
        }

        public void AddStation1Command()
        {
            GetCommunicationHelper(1).ReLoadAction += () =>
            {
                FirstTestStation.Cur.PowerOFF();
                Thread.Sleep(OtherParamHelper.Cur.CardPowerOnDelayTime.GetValue);
                FirstTestStation.Cur.PowerON();
            };
        }

        public void AddStation2Command() {
            SiteCommunicationHelper communicationHelper = GetCommunicationHelper(2);

            communicationHelper.ReLoadAction += () =>
            {
                SecondTestStation.Cur.PowerOFF();
                Thread.Sleep(OtherParamHelper.Cur.CardPowerOnDelayTime.GetValue);
                SecondTestStation.Cur.PowerON();
            };

            CheckMTPCommand CheckMoveSfr = new CheckMTPCommand("MoveSfr");
            CheckMTPCommand CheckMove = new CheckMTPCommand("MOVE");

            CheckMove.SetCheckAction(s => {
                WriteToUser($"{communicationHelper.Name}开始响应：{CheckMove.Command}");
                MTP mc2Test = new MTP();
                mc2Test.command = CheckMove.Command;
                mc2Test.text = s.text;
                try
                {
                    double res = double.Parse(mc2Test.text);
                    Motion.Aixs.Light.Aix_Light_1.Cur.Mov(res, true, true);
                }
                catch (Exception ex)
                {
                    writeErrToUser(ex.Message); ;
                }

                mc2Test.result = "OK";
                communicationHelper.Connect.Send(mc2Test);
                WriteToUser($"{communicationHelper.Name}发送：{mc2Test.command}, {mc2Test.text}, {mc2Test.result}");
            });

            CheckMoveSfr.SetCheckAction(s =>
            {
                WriteToUser($"{communicationHelper.Name}开始响应：{CheckMoveSfr.Command}");
                MTP mc2Test = new MTP();
                mc2Test.command = s.command;
                mc2Test.text = s.text;

                try
                {
                    mc2Test.result = "OK";
                }
                catch (Exception ex)
                {
                    mc2Test.result = "NG";
                    WriteToUser($"{communicationHelper.Name}Error:{ex.Message}");
                }

                communicationHelper.Connect.Send(mc2Test);
                WriteToUser($"{communicationHelper.Name}发送：{mc2Test.command}, {mc2Test.text}, {mc2Test.result}");
            });

            communicationHelper.checkMTPCommandsList.Add(CheckMoveSfr);
            communicationHelper.checkMTPCommandsList.Add(CheckMove);
            AddCheckCurrentCommand(communicationHelper,1);
        }

        public void AddStation3Command()
        {
            SiteCommunicationHelper communicationHelper = GetCommunicationHelper(3);
            communicationHelper.ReLoadAction = () => {
                ThirdTestStation.Cur.PowerOFF();
                Thread.Sleep(OtherParamHelper.Cur.CardPowerOnDelayTime.GetValue);
                ThirdTestStation.Cur.PowerON();
            };

            CheckMTPCommand Checklight = new CheckMTPCommand("LIGHT");
            CheckMTPCommand CheckMoveLowLight = new CheckMTPCommand("MoveLowLight");
            CheckMTPCommand CheckMoveColorTemp = new CheckMTPCommand("MoveColorTemp");

            CheckMoveLowLight.SetCheckAction(s =>
            {
                WriteToUser($"{communicationHelper.Name}开始响应：{CheckMoveLowLight.Command}");
                MTP mc2Test = new MTP();
                mc2Test.command = s.command;
                mc2Test.text = s.text;

                try
                {
                    if (SetVolToStation3(OtherParamHelper.Cur.TestVol.GetValue))
                    {
                        ThirdTestStation.Cur.PowerOFF();
                        Thread.Sleep(100);
                        ThirdTestStation.Cur.PowerON();
                        WriteToUser($"{ThirdTestStation.Cur.LocalStation}治具设置电压后重新上电！");

                        if (StaticIOHelper.Fun_MoveLowLight(out string error))
                        {
                            ConnectFactory.GetOpt(2).TurnOffChannel(0);
                            mc2Test.result = "OK";
                            WriteToUser("切换到低照度（黑桶）完成");
                        }
                        else
                        {
                            mc2Test.result = "NG";
                            Motion.StaticInitial.Motion.WriteErrToUser($"{communicationHelper.Name}:{error}");
                        }
                    }
                    else
                    {
                        mc2Test.result = "NG";
                        Motion.StaticInitial.Motion.WriteErrToUser($"{communicationHelper.Name}:电压设置为{OtherParamHelper.Cur.TestVol.GetValue}V失败！");
                    }
                }
                catch (Exception ex)
                {
                    mc2Test.result = "NG";
                    WriteToUser($"{communicationHelper.Name}Error:{ex.Message}");
                }

                communicationHelper.Connect.Send(mc2Test);
                WriteToUser($"{communicationHelper.Name}发送：{mc2Test.command}, {mc2Test.text}, {mc2Test.result}");
            });
            CheckMoveColorTemp.SetCheckAction(s =>
            {
                WriteToUser($"{communicationHelper.Name}开始响应：{CheckMoveColorTemp.Command}");
                MTP mc2Test = new MTP();
                mc2Test.command = s.command;
                mc2Test.text = s.text;

                try
                {
                    if (StaticIOHelper.Fun_MoveColorTemp(out string error))
                    {
                        ConnectFactory.GetOpt(2).TurnOnChannel(0);
                        mc2Test.result = "OK";
                        WriteToUser("切换到三色温（白桶）完成");
                    }
                    else
                    {
                        mc2Test.result = "NG";
                        Motion.StaticInitial.Motion.WriteErrToUser($"{communicationHelper.Name}:{error}");
                    }
                }
                catch (Exception ex)
                {
                    mc2Test.result = "NG";
                    WriteToUser($"{communicationHelper.Name}Error:{ex.Message}");
                }

                communicationHelper.Connect.Send(mc2Test);
                WriteToUser($"{communicationHelper.Name}发送：{mc2Test.command}, {mc2Test.text}, {mc2Test.result}");
            });
            Checklight.SetCheckAction(s =>
            {
                WriteToUser($"{communicationHelper.Name}开始响应：{Checklight.Command}");
                MTP mc2Test = new MTP();
                mc2Test.command = s.command;
                mc2Test.text = s.text;
                try
                {
                    switch (s.text)
                    {
                        case "1":
                            ConnectFactory.GetOpt(2)?.TurnOffChannel(1);
                            ConnectFactory.GetOpt(2)?.TurnOnChannel(0);
                            break;

                        case "2":
                            ConnectFactory.GetOpt(2)?.TurnOffChannel(0);
                            ConnectFactory.GetOpt(2)?.TurnOnChannel(1);
                            break;

                        case "3":

                            StaticIOHelper.Fun_Light3();
                            break;
                    }
                    mc2Test.result = "OK";
                }
                catch (Exception ex)
                {
                    mc2Test.result = "NG";
                    mc2Test.text = ex.Message;
                }
                communicationHelper.Connect.Send(mc2Test);
                WriteToUser($"{communicationHelper.Name}发送：{mc2Test.command}, {mc2Test.text}, {mc2Test.result}");
            });
            
            communicationHelper.checkMTPCommandsList.Add(Checklight);
            communicationHelper.checkMTPCommandsList.Add(CheckMoveLowLight);
            communicationHelper.checkMTPCommandsList.Add(CheckMoveColorTemp);

            AddCheckCurrentCommand(communicationHelper, 2);
            AddChangeAWBCommand(communicationHelper);
        }

        public void AddStation4Command()
        {
            SiteCommunicationHelper communicationHelper = GetCommunicationHelper(4);
            communicationHelper.ReLoadAction = () => {
                FourTestStation.Cur.PowerOFF();
                Thread.Sleep(OtherParamHelper.Cur.CardPowerOnDelayTime.GetValue);
                FourTestStation.Cur.PowerON();
            };

            CheckMTPCommand RePower = new CheckMTPCommand("RePower");
            CheckMTPCommand SwitchIlluminance = new CheckMTPCommand("SWITCHILLUMINANCE");
            CheckMTPCommand GetResultData = new CheckMTPCommand("GETRESULTDATA");
            CheckMTPCommand ClosePlanarLight = new CheckMTPCommand("CLOSEPLANARLIGHT");
            CheckMTPCommand CloseProductLight = new CheckMTPCommand("CLOSEPRODUCTLIGHT");

            SwitchIlluminance.SetCheckAction(s =>
            {
                WriteToUser($"{communicationHelper.Name}开始响应：{SwitchIlluminance.Command}");
                MTP mc2Test = new MTP();
                mc2Test.command = s.command;
                mc2Test.text = s.text;

                try
                {
                    mc2Test.result = "OK";
                }
                catch (Exception ex)
                {
                    mc2Test.result = "NG";
                    WriteToUser($"{communicationHelper.Name}Error:{ex.Message}");
                }

                communicationHelper.Connect.Send(mc2Test);
                WriteToUser($"{communicationHelper.Name}发送：{mc2Test.command}, {mc2Test.text}, {mc2Test.result}");
            });
            RePower.SetCheckAction(s =>
            {
                WriteToUser($"{communicationHelper.Name}开始响应：{RePower.Command}");
                MTP mc2Test = new MTP();
                mc2Test.command = s.command;
                mc2Test.text = s.text;

                try
                {
                    StaticIOHelper.Out_Power2Channel2.Out_OFF();
                    Thread.Sleep(500);
                    StaticIOHelper.Out_Power2Channel2.Out_ON();
                    mc2Test.result = "OK";
                }
                catch (Exception ex)
                {
                    mc2Test.result = "NG";
                    WriteToUser($"{communicationHelper.Name}Error:{ex.Message}");
                }

                communicationHelper.Connect.Send(mc2Test);
                WriteToUser($"{communicationHelper.Name}发送：{mc2Test.command}, {mc2Test.text}, {mc2Test.result}");

            });
            ClosePlanarLight.SetCheckAction(s =>
            {
                WriteToUser($"{communicationHelper.Name}开始响应：{SwitchIlluminance.Command}");
                MTP mc2Test = new MTP();
                mc2Test.command = s.command;
                mc2Test.text = s.text;

                try
                {

                    ConnectFactory.GetOpt(3)?.TurnOffChannel(1);
                    ConnectFactory.GetOpt(0)?.TurnOffChannel(1);

                    Thread.Sleep(300);
                    mc2Test.result = "OK";
                }
                catch (Exception ex)
                {
                    mc2Test.result = "NG";
                    WriteToUser($"{communicationHelper.Name}Error:{ex.Message}");
                }

                communicationHelper.Connect.Send(mc2Test);
                WriteToUser($"{communicationHelper.Name}发送：{mc2Test.command}, {mc2Test.text}, {mc2Test.result}");

            });
            CloseProductLight.SetCheckAction(s =>
            {
                WriteToUser($"{communicationHelper.Name}开始响应：{SwitchIlluminance.Command}");
                MTP mc2Test = new MTP();
                mc2Test.command = s.command;
                mc2Test.text = s.text;

                try
                {
                    StaticIOHelper.Out_Power2Channel2.Out_OFF();
                    mc2Test.result = "OK";
                }
                catch (Exception ex)
                {
                    mc2Test.result = "NG";
                    WriteToUser($"{communicationHelper.Name}Error:{ex.Message}");
                }

                communicationHelper.Connect.Send(mc2Test);
                WriteToUser($"{communicationHelper.Name}发送：{mc2Test.command}, {mc2Test.text}, {mc2Test.result}");

            });
            GetResultData.SetCheckAction(s =>
            {
                if (Motion.Process.Process_AutoRun.Cur.IsProcessRunning)
                {
                    WriteToUser($"{communicationHelper.Name}开始响应：{GetResultData.Command}");

                    MTP mc2Test = new MTP();
                    mc2Test.command = s.command;
                    mc2Test.result = FourTestStation.Cur.GetResult();
                    mc2Test.text = FourTestStation.Cur.AllInfo();

                    communicationHelper.Connect.Send(mc2Test);
                    WriteToUser($"{communicationHelper.Name}发送：{mc2Test.command}, {mc2Test.text}, {mc2Test.result}");
                }
                else
                {
                    WriteToUser($"{communicationHelper.Name}开始响应：{GetResultData.Command}，非自动运行，跳过！");
                }
            });

            communicationHelper.checkMTPCommandsList.Add(RePower);
            communicationHelper.checkMTPCommandsList.Add(ClosePlanarLight);
            communicationHelper.checkMTPCommandsList.Add(SwitchIlluminance);
            communicationHelper.checkMTPCommandsList.Add(GetResultData);
        }

        public void AddStation5Command() { }

        public void AddStation6Command() { }

        private void writeErrToUser(string message)
        {
            Motion.StaticInitial.Motion.WriteErrToUser(message);
        }

        private void WriteToUser(string str)
        {
            Motion.StaticInitial.Motion.WriteToUser(str);
        }

        private bool GetCurrent(ProgrammablePowerEntity programmablePower, Power3Demo.ChannelIndex index, out string current, out string voltage)
        {
            current = string.Empty;
            voltage = string.Empty;

            return programmablePower.CheckCurrentAndGetVoltage(index, out current, out voltage);
        }

        public bool SetVolToStation3(double vol = 5.5)
        {
            switch (Motion.Aixs.RotatedMovNextHelper.tagPos[2])
            {
                case "A":
                    return SetVol(ConnectFactory.PowerSerialPort_1, Power3Demo.ChannelIndex.First, vol);

                case "B":
                    return SetVol(ConnectFactory.PowerSerialPort_1, Power3Demo.ChannelIndex.Second, vol);

                case "C":
                    return SetVol(ConnectFactory.PowerSerialPort_2, Power3Demo.ChannelIndex.First, vol);

                case "D":
                    return SetVol(ConnectFactory.PowerSerialPort_2, Power3Demo.ChannelIndex.Second, vol);

                case "E":
                    return SetVol(ConnectFactory.PowerSerialPort_3, Power3Demo.ChannelIndex.First, vol);

                case "F":
                    return SetVol(ConnectFactory.PowerSerialPort_3, Power3Demo.ChannelIndex.Second, vol);
            }

            return false;
        }

        private bool SetVol(ProgrammablePowerEntity programmablePower, Power3Demo.ChannelIndex index, double vol)
        {
            FinalTestMachine.Motion.StaticInitial.Motion.WriteToUser($"== change channel {index} to {vol} V==");
            programmablePower.PowerChannelFactory.operateChannelHelpersList[index].channelSetting.Vol = vol;
            programmablePower.PowerChannelFactory.operateChannelHelpersList[index].Set_channel();

            System.Threading.Thread.Sleep(Motion.OtherParamHelper.Cur.ChangeVolDelayTime.GetValue);

            try
            {
                double tempVol = double.Parse(Get_Vol(programmablePower, index));

                if (Math.Abs(tempVol - vol) <= 0.1)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                Motion.StaticInitial.Motion.WriteToUser($"设置电压失败！{ex.Message}");
                return false;
            }
        }

        public string Get_Vol(ProgrammablePowerEntity programmablePower, Power3Demo.ChannelIndex index)
        {
            string strTemp = null;

            programmablePower.PowerChannelFactory.operateChannelHelpersList[index].tcpConnect.GetMsg();//清空
            programmablePower.PowerChannelFactory.operateChannelHelpersList[index].tcpConnect.Send("MEAS:VOLT?");
            Thread.Sleep(100);
            int i = 0;
            while (true)
            {
                strTemp = programmablePower.PowerChannelFactory.operateChannelHelpersList[index].tcpConnect.GetMsg();
                if (strTemp != null)
                {
                    break;
                }
                if (i > 1000 / 10 * 3)
                {
                    throw new Exception("查询电压超时！");
                }
                i++;
                Thread.Sleep(10);
            }

            Motion.StaticInitial.Motion.WriteToUser($"查询电压为:{strTemp}！");

            if (string.IsNullOrEmpty(strTemp))
            {
                return "0";
            }
            else
            {
                return double.Parse(strTemp).ToString();
            }
        }

        /// <summary>
        /// 为站位通讯添加检查电流和电压的命令和回复内容
        /// </summary>
        /// <param name="communicationHelper"></param>
        /// <param name="currentIndex"></param>
        private void AddCheckCurrentCommand(SiteCommunicationHelper communicationHelper,int currentIndex)
        {
            CheckMTPCommand CheckCurrent = new CheckMTPCommand("CURRENT");
            CheckCurrent.SetCheckAction(s =>
            {
                WriteToUser($"{communicationHelper.Name}开始响应：{CheckCurrent.Command}");
                MTP mc2Test = new MTP();
                mc2Test.command = s.command;
                mc2Test.text = s.text;

                string current = string.Empty;
                string voltage = string.Empty;

                bool result = false;

                try
                {
                    if (!string.IsNullOrEmpty(s.command) || s.command == "CURRENT")
                    {
                        switch (Motion.Aixs.RotatedMovNextHelper.tagPos[currentIndex])
                        {
                            case "A":
                                result = GetCurrent(ConnectFactory.PowerSerialPort_1, Power3Demo.ChannelIndex.First, out current, out voltage);
                                WriteToUser("获取A载具程控电源1_1通道电流为：" + current + ";电压为：" + voltage);
                                break;

                            case "B":
                                result = GetCurrent(ConnectFactory.PowerSerialPort_1, Power3Demo.ChannelIndex.Second, out current, out voltage);
                                WriteToUser("获取B载具程控电源1_2通道电流为：" + current + ";电压为：" + voltage);
                                break;

                            case "C":
                                result = GetCurrent(ConnectFactory.PowerSerialPort_2, Power3Demo.ChannelIndex.First, out current, out voltage);
                                WriteToUser("获取C载具程控电源2_1通道电流为：" + current + ";电压为：" + voltage);
                                break;

                            case "D":
                                result = GetCurrent(ConnectFactory.PowerSerialPort_2, Power3Demo.ChannelIndex.Second, out current, out voltage);
                                WriteToUser("获取D载具程控电源2_2通道电流为：" + current + ";电压为：" + voltage);
                                break;

                            case "E":
                                result = GetCurrent(ConnectFactory.PowerSerialPort_3, Power3Demo.ChannelIndex.First, out current, out voltage);
                                WriteToUser("获取E载具程控电源3_1通道电流为：" + current + ";电压为：" + voltage);
                                break;

                            case "F":
                                result = GetCurrent(ConnectFactory.PowerSerialPort_3, Power3Demo.ChannelIndex.Second, out current, out voltage);
                                WriteToUser("获取E载具程控电源3_2通道电流为：" + current + ";电压为：" + voltage);
                                break;
                        }

                        mc2Test.text = current + "_" + voltage;

                        mc2Test.result = result ? "OK" : "NG";
                    }
                    else
                    {
                        mc2Test.result = "NG";
                    }
                }
                catch (Exception ex)
                {
                    mc2Test.result = "NG";
                    mc2Test.text = ex.Message;
                }

                communicationHelper.Connect.Send(mc2Test);
                WriteToUser($"{communicationHelper.Name}发送：{mc2Test.command}, {mc2Test.text}, {mc2Test.result}");
            });
            communicationHelper.checkMTPCommandsList.Add(CheckCurrent);
        }

        /// <summary>
        /// 调节色温
        /// </summary>
        private void AddChangeAWBCommand(SiteCommunicationHelper communicationHelper)
        {
            string command = "CHANGEAWB";
            CheckMTPCommand checkMTPCommand = new CheckMTPCommand(command);
            checkMTPCommand.SetCheckAction(s =>
            {
                WriteToUser($"{communicationHelper.Name}开始响应：{checkMTPCommand.Command}");
                if (!string.IsNullOrEmpty(s.text))
                {
                    string[] data = s.text.Split(new char[] { ',' });
                    if (data.Length == 2)
                    {
                        string errInfo = "";
                        if (AWBManager.AWB1.WriteData(data[0],out errInfo))
                        {
                            if (AWBManager.AWB1.WriteValue(data[1],out errInfo))
                            {
                                WriteToUser($"成功发送数据：{data[0]}、{data[1]}");
                            }
                            else
                            {
                                WriteToUser("修改数值失败:");
                            }
                        }
                        else
                        {
                            WriteToUser("修改色温失败:" + errInfo);
                        }
                        
                        
                        
                    }
                    else
                    {
                        writeErrToUser($"{communicationHelper.Name}接收到的AWB数据格式有误{s.text}");
                        ResponseMessage(communicationHelper, command, "NG");
                        return;
                    }
                }
                else
                {
                    AWBManager.AWB1.WriteData("2900");
                    AWBManager.AWB1.WriteValue("200");
                }
                ResponseMessage(communicationHelper, command);
            });
            communicationHelper.checkMTPCommandsList.Add(checkMTPCommand);
        }

        public void ResponseMessage(SiteCommunicationHelper communicationHelper,string Command, string result = "OK", string text = "")
        {
            MTP response = new MTP();
            response.command = Command;

            response.result = result;
            communicationHelper.Connect.Send(response);
            WriteToUser($"{communicationHelper.Name}发送：{response.command}, {response.text}, {response.result}");
        }
    }
}
